//Random
class ShuiJiUtil {
    //seed
    zhongzhi;
    //_defaultRandom
    static morenzhi;

    constructor(seed) {
        this.zhongzhi = seed || Date.now();
    }

    static get defaultRandom() {
        if (!ShuiJiUtil.morenzhi) {
            ShuiJiUtil.morenzhi = new ShuiJiUtil();
        }
        return ShuiJiUtil.morenzhi;
    }

    static get insideUnitCircle() {
        return ShuiJiUtil.defaultRandom.insideUnitCircle;
    }

    static get onUnitCircle() {
        return ShuiJiUtil.defaultRandom.onUnitCircle;
    }

    static get value() {
        return ShuiJiUtil.defaultRandom.value;
    }

    //range   cs1<= x <= cs2
    static getSuiJiShu(cs1, cs2) {
        return ShuiJiUtil.defaultRandom.sui_ji(cs1, cs2);
    }
    //floatRange
    static getSuiJiFuDianShu(cs1, cs2) {
        return ShuiJiUtil.defaultRandom.sui_ji_fuDianShu(cs1, cs2);
    }
    //floatRange
    sui_ji_fuDianShu(canshu1, canshu2) {
        canshu2 = canshu2 || 0;
        canshu1 = canshu1 || 0;
        canshu2 = Math.max(canshu2, canshu1);
        canshu1 = Math.min(canshu2, canshu1);
        this.zhongzhi = (9301 * this.zhongzhi + 49297) % 233280;
        return canshu1 + (this.zhongzhi / 233280) * (canshu2 - canshu1);
    }
    //range
    sui_ji(canshu1, canshu2) {
        return Math.round(this.sui_ji_fuDianShu(canshu1, canshu2));
    }

    get insideUnitCircle() {
        const v2_ano538 = this.sui_ji_fuDianShu(0, 360);
        const v2_ano539 = this.sui_ji_fuDianShu(0, 1);
        return cc.v2(
            v2_ano539 * Math.sin(v2_ano538 * Math.PI / 180),
            v2_ano539 * Math.cos(v2_ano538 * Math.PI / 180)
        );
    }

    get onUnitCircle() {
        const v2_ano540 = this.sui_ji_fuDianShu(0, 360);
        return cc.v2(
            Math.sin(v2_ano540 * Math.PI / 180),
            Math.cos(v2_ano540 * Math.PI / 180)
        );
    }

    get value() {
        return this.sui_ji_fuDianShu(0, 1);
    }
    //randomNum
    static suiJiShuZi(canshu1, canshu2) {
        const v2a = [];
        if (canshu1 <= canshu2) {
            for (let v3a = 0; v3a < canshu1; v3a++) {
                v2a.push(v3a);
            }
            return v2a;
        }
        while (v2a.length < canshu2) {
            const v3_ano542 = Math.round(Math.random() * (canshu1 - 1));
            if (v2a.indexOf(v3_ano542) === -1) {
                v2a.push(v3_ano542);
            }
        }
        return v2a;
    }
}

/**
 * 小游戏平台SDK工具封装，目前只支持微信和抖音平台
 */
// export namespace MiniGameSdk {
export const MiniGameSdk = (() => {
    const ISize = {
        width: 0,
        height: 0
    }

    const IPosition = {
        top: 0,
        left: 0
    }

    const EPlatform = {
        /**
         * 当前开发环境
         */
        DEVELOP: "DEVELOP",

        /**
         * 微信小游戏环境
         */
        WECHAT: "WECHAT",

        /**
         * 抖音小游戏环境
         */
        BYTEDANCE: "BYTEDANCE",
    }

    function isWechat() {
        //@ts-ignore
        return window.wx !== null && window.wx !== undefined;
    }

    function isBytedance() {
        //@ts-ignore
        return window.tt !== null && window.tt !== undefined;
    }

    /**
     * 获得平台标识。只支持微信、抖音和开发环境。
     * @returns 
     */
    function getPlatformType() {
        if (isWechat()) {
            return EPlatform.WECHAT;
        } else if (isBytedance()) {
            return EPlatform.BYTEDANCE;
        } else {
            return EPlatform.DEVELOP;
        }
    }

    function getPlatformSystemWindowSize() {
        let platform = getPlatformType();
        let sys;
        if (platform === EPlatform.WECHAT) {
            // @ts-ignore
            sys = wx.getSystemInfoSync();
        } else if (platform === EPlatform.BYTEDANCE) {
            // @ts-ignore
            sys = tt.getSystemInfoSync();
        }

        let size = { width: 0, height: 0 };
        if (sys) {
            size.width = sys.windowWidth;
            size.height = sys.windowHeight;
        }

        return size;
    }

    /**
     * 插屏广告。微信抖音都支持！
     */
    class ADInterstitial {
        _adUid;
        _interstitial;

        get aduid() {
            return this._adUid;
        }

        /**
         * 插屏广告。只需要显示即可，让用户自主关闭。
         * @param adUid 广告UID，后端配置
         */
        constructor(adUid) {
            this._adUid = adUid;
        }

        /**
         * 显示插屏广告
         * @returns 
         */
        show() {
            let platform = getPlatformType();
            if (platform === EPlatform.DEVELOP) {
                this._interstitial = null;
                return;
            }

            // @ts-ignore
            if (isWechat() && !wx.createInterstitialAd) {
                console.warn('wechat unsupport interstitial AD!');
                this._interstitial = null;
                return;
            }

            // @ts-ignore
            if (isBytedance() && !tt.createInterstitialAd) {
                console.warn('bytedance unsupport interstitial AD!');
                this._interstitial = null;
                return;
            }


            // 显示的时候才加载
            if (this._interstitial) {
                this._interstitial.load(); // 会在onLoad里面自动show
            } else {
                if (platform === EPlatform.WECHAT) {
                    // @ts-ignore
                    this._interstitial = wx.createInterstitialAd({ adUnitId: this._adUid });
                } else if (platform === EPlatform.BYTEDANCE) {
                    // @ts-ignore
                    this._interstitial = tt.createInterstitialAd({ adUnitId: this._adUid });
                } else {
                    this._interstitial = null;
                }

                this._interstitial?.onLoad(() => {
                    console.log('load interstitial ad success');
                    this._interstitial.show().catch((err) => {
                        console.log('catch interstitial ad error:', err);
                    });
                });

                this._interstitial?.onError((err) => {
                    console.log('interstitial ad on error:', err);
                });
            }
        }

        /**
         * 销毁插屏广告
         */
        destory() {
            this._interstitial?.destroy();
        }
    }

    /**
     * 横幅广告。微信抖音都支持！
     */
    class ADBanner {
        _adUid;
        _banner;

        get aduid() {
            return this._adUid;
        }

        /**
         * 抖音和微信都支持
         * 横幅广告。预估宽度默认为300，预估高度为140。如果你不确定就按默认值来。
         * @param adUid 广告UID，后端配置
         * @param isTop 是否在屏幕顶部展示。内部会自动居中计算位置。
         * @param bannerWidth 横幅广告的预估宽度。默认300
         * @param autoShow 广告加载完成后是否立刻显示，默认为不显示
         */
        constructor(adUid, param, bannerWidth = 300, autoShow = false) {
            this._adUid = adUid;
            this.create(autoShow, bannerWidth, param); // 默认300比较合适
        }

        create(autoShow, bannerWidth, param) {
            let platform = getPlatformType();
            if (platform === EPlatform.DEVELOP) {
                this._banner = null;
                return;
            }

            this.destroy();

            let winSize = getPlatformSystemWindowSize();

            let height = bannerWidth * 0.4;
            let top = 0, left = 0;

            // if (typeof param === "boolean") {
            //     left = (winSize.width - bannerWidth) / 2
            //     top = param ? 5 : (winSize.height - height);
            // } else {
            //     left = param.left;
            //     top = param.top;
            // }
            left = (winSize.width - bannerWidth) / 2
                // top = param ? 5 : (winSize.height - height);
            top = winSize.height - height
            console.log("广告距离顶部距离：",top)
            let params = {
                adUnitId: this._adUid,
                adIntervals: 30,// 自动刷新频率不能小于30秒
                style: { left: left, top: top + 20, width: bannerWidth }
            }

            if (platform === EPlatform.WECHAT) {
                // @ts-ignore
                this._banner = wx.createBannerAd(params);
            } else if (platform === EPlatform.BYTEDANCE) {
                // @ts-ignore
                this._banner = tt.createBannerAd(params);
            } else {
                this._banner = null;
            }

            this._banner?.onError((err) => {
                console.log('ad banner error:', err);
            });

            this._banner?.onLoad(() => {
                autoShow && this._banner.show();
            });
        }

        /**
         * 显示横幅广告
         */
        show() {
            this._banner?.show();
        }

        /**
         * 隐藏横幅广告
         */
        hide() {
            this._banner?.hide();
        }

        /**
         * 销毁横幅广告
         */
        destroy() {
            this._banner?.destroy();
        }
    }

    /**
     * 原生模板广告。微信支持，抖音不支持！
     */
    class ADCustom {
        _adUid;
        _adCustom;

        get aduid() {
            return this._adUid;
        }
        /**
         * 由于原生模板广告在微信服务后端可以定制宽度大小，个数，缩放比例等，所以位置调整要根据设置的宽度来定。抖音不支持！
         * @param adUid 广告UID，后端配置
         * @param top 从左上角开始，距离屏幕顶部的距离。注意：这个数据为设备屏幕宽度width。如果需要获取屏幕的像素，需要乘以设备像素比Pixel-Ratio，例如iPhone 13 Pro的Pixel-Ratio为3，像素为Width*3。
         * @param left 从左上角开始，距离屏幕最左边的距离。注意：这个数据为设备屏幕宽度width。如果需要获取屏幕的像素，需要乘以设备像素比Pixel-Ratio，例如iPhone 13 Pro的Pixel-Ratio为3，像素为Width*3。
         * @param scale 原生模板广告的尺寸，默认为1，即100%。此值在微信服务后端广告中获得，默认为100%，目前有100%，90%，80%三种，一般情况不用修改。若有修改，记得传入值，例如90%就传入0.9。
         */
        constructor(adUid, top = 0, left = 0, scale = 1.0) {
            this._adUid = adUid;
            this.createCustomAd(top, left, scale);
        }

        createCustomAd(top, left, scale) {
            let platform = getPlatformType();
            if (platform === EPlatform.DEVELOP || platform === EPlatform.BYTEDANCE) {
                this._adCustom = null;
                console.log('develop or bytedance env not support custom Ad:', platform);
                return;
            }

            this.destroy();
            // 原生模板5个应用宽度为375，若设置了缩放比例，则宽度也需要设置
            // let width = 375 * this._scale;
            // let newLeft = (sys.windowWidth - width) / 2;
            // let newTop = sys.windowHeight / 2; // 120是预估高度

            // @ts-ignore
            this._adCustom = wx.createCustomAd({
                adUnitId: this._adUid,
                //adIntervals: 35, // 自动刷新频率不能小于30秒
                style: { left: left, top: top, fixed: true } // fixed这个参数只适用于小程序环境
            });

            this._adCustom?.onError((err) => {
                console.log('ad custom error:', err);
            });
        }

        /**
         * 显示原生模板广告
         */
        show() {
            this._adCustom?.show();
        }

        /**
         * 隐藏原生模板广告
         */
        hide() {
            this._adCustom?.hide();
        }

        /**
         * 销毁原生模板广告
         */
        destroy() {
            this._adCustom?.destroy();
        }
    }


    /**
     * 视频广告用户点击行为结果
     */
    const EAdVideoResult = {
        /**
         * 用户看完了广告，游戏可发放奖励。
         */
        ACCEPT: "ACCEPT",

        /**
         * 用户中途关闭了广告，即未看完状态。不可发放奖励。
         */
        REJECT: "REJECT",

        /**
         * 广告组件内部发生了错误。不可发放奖励。
         */
        ERROR: "ERROR",
    }

    /**
     * 激励视频广告。微信和抖音都支持！
     */
    class ADVideo {
        _adUid;
        _adVideo = null;

        get aduid() {
            return this._adUid;
        }

        /**
         * 激励视频广告
         * @param adUid 广告UID，后端配置
         */
        constructor(adUid) {
            this._adUid = adUid;
        }

        /**
         * 由于微信和抖音视频广告机制不同，微信可以看的视频广告个数只有0和1个，抖音平台则可以看0~maxVideoCount
         * @param onResult 两个参数：第一个res是EAdVideoResult定义，第二count是用户看了多少个视频广告。
         * @param target onResult的拥有者
         * @param maxVideoCount 可以连续看最大视频个数，可最大化商业效率。默认为3个。
         * @returns 
         */
        show(onResult, target, maxVideoCount = 3) {
            let callback = (state, count) => {
                onResult?.call(target, state, count);
            }

            let platform = getPlatformType();
            if (platform === EPlatform.DEVELOP) {
                callback(EAdVideoResult.ACCEPT, 1);
                this._adVideo = null;
                return;
            }

            let onAdVideoClosed = (res) => {
                this._adVideo?.offClose(onAdVideoClosed);// 必须注销掉上一次的回调，否则可能产生多次回调
                // 用户点击关闭广告按钮，基础库版本<2.1.0时，res是undefined
                if (platform === EPlatform.WECHAT) {
                    if (res && res.isEnded || res === undefined) {
                        callback(EAdVideoResult.ACCEPT, 1);
                    } else {
                        callback(EAdVideoResult.REJECT, 0);
                    }
                } else if (platform === EPlatform.BYTEDANCE) {
                    let resConverted = res;
                    if (resConverted && resConverted.count > 0) {
                        callback(EAdVideoResult.ACCEPT, resConverted.count);
                    } else {
                        callback(EAdVideoResult.REJECT, 0);
                    }
                }
            }

            this._adVideo?.offClose(onAdVideoClosed);// 注销掉上一次的回调，否则可能产生多次回调

            if (platform === EPlatform.WECHAT) {
                // @ts-ignore
                this._adVideo = wx.createRewardedVideoAd({
                    adUnitId: this._adUid
                });
            } else if (platform === EPlatform.BYTEDANCE) {
                // @ts-ignore
                this._adVideo = tt.createRewardedVideoAd({
                    adUnitId: this._adUid,
                    multiton: true,
                    multitonRewardMsg: ['多1次奖励', '再多一次奖励', '再多一次奖励'],
                    multitonRewardTimes: maxVideoCount,
                });
            } else {
                this._adVideo = null;
            }


            this._adVideo?.onLoad(() => {
                console.log('ad video load success');
            });

            this._adVideo?.onError((err) => {
                console.log('ad video error:', err);
                callback(EAdVideoResult.ERROR, 0);
            });

            this._adVideo?.onClose(onAdVideoClosed);

            this._adVideo?.show().catch(() => {
                this._adVideo?.load().then(() =>
                    this._adVideo?.show()).catch((err) => {
                        console.log('catch video ad error:', err);
                        callback(EAdVideoResult.ERROR, 0);
                    });
            });
        }

        /**
         * 销毁视频广告
         */
        destory() {
            this._adVideo?.destory();
        }
    }

    /**
     * 横幅广告的位置
     */
    const EAdBannerLocation = {
        /**
         * 屏幕顶部
         */
        TOP: "TOP",

        /**
         * 屏幕底部
         */
        BOTTOM: "BOTTOM"
    }

    /**
     * 广告管理器
     */
    class AdvertManager {

        static _instance;

        static get instance() {
            if (!AdvertManager._instance) {
                AdvertManager._instance = new AdvertManager();
            }
            return AdvertManager._instance;
        }

        _video;
        _interstitial;
        _banner;
        _custom;
        _custom2;
        _customLeft3;
        _customRight3;
        blnFromShare = false;
        constructor() {

        }

        /**
         * 预加载横幅广告，不会显示。只有你在调用showBanner时才会显示。
         * 可重复调用，但是会销毁上一次的实例。一般情况，全局有一个就行了，太多占用内存，而且没必要。
         * @param adUid 广告UID
         * @param location 位置有两种情况：1、可以传入枚举值，默认上方; 2、可以自定义位置传入IPosition，注意IPosition中的top和left跟平台的top,left是一致（没有乘以设备像素比ratio），需要开发者自己调试位置
         * @param scale 默认为跟屏幕一样的宽度，可以通过设置缩放比例来调整大小。当然，平台有规定最大或最小宽度，函数内部会自动计算。
         */
        loadBanner(adUid, location = EAdBannerLocation.TOP, scale = 1.0) {
            this._banner?.destroy();
            let size = getPlatformSystemWindowSize();
            // 当 style.width 小于 300 时，会取作 300。 当 style.width 大于屏幕宽度时，会取作屏幕宽度。
            let width = size.width * scale;
            width = width < 300 ? 300 : width; // 最小值矫正
            width = width > size.width ? size.width : width; //最大值矫正
            width = 300;
            //this._banner = typeof location === 'number' ? new ADBanner(adUid, location === EAdBannerLocation.BOTTOM, width, false) : new ADBanner(adUid, location, width, false);
            this._banner = typeof location === 'number' ? new ADBanner(adUid, location === EAdBannerLocation.TOP, width, false) : new ADBanner(adUid, location, width, false);
        }

        /**
         * 显示横幅广告
         */
        showBanner() {
            if (this._banner) {
                this._banner.show();
            } else {
                console.error('MiniGameSDK: banner is null, you must call loadBanner(...) first!');
            }
        }

        /**
         * 隐藏横幅广告
         */
        hideBanner() {
            this._banner?.hide();
        }

        /**
         * 弹出插屏广告
         * @param adUid 广告单元id
         */
        showInterstitial(adUid) {
            if (this._interstitial && this._interstitial.aduid === adUid) {
                this._interstitial.show();
            } else {
                this._interstitial?.destory();
                this._interstitial = new ADInterstitial(adUid);
                this._interstitial.show();
            }
        }

        _interAd; //插屏广告
        /** 初始化插屏广告 */
        loadInterAd(AD_UNIT_ID) {
            if (isWechat()) {
                this._interAd = wx.createInterstitialAd({ adUnitId: AD_UNIT_ID })

                if (!this._interAd) {
                    console.info('创建插屏广告组件 fail')
                    return
                }

                this._interAd.onError((e) => {
                    console.info('插屏error', e)
                })

                this._interAd.onClose(() => {
                    // TODO
                })
            }

        }

        /** 显示插屏广告广告 */
        showInterAd() {
            if (isWechat()) {
                if (this._interAd) {
                    this._interAd.show()
                        .then(() => { console.info("插屏show success") })
                        .catch((err) => {
                            console.info('_interAd show error', err)

                            // 失败后重新加载广告
                            this._interAd.load()
                                .catch((err) => {
                                    console.info('插屏load', err)
                                })
                        })
                }
            }

        }

        /**
         * 加载原生模板广告，不会显示。只有你在调用showCustom时才会显示。
         * 由于原生模板广告在微信服务后端可以定制宽度大小，个数，缩放比例等，所以位置调整要根据设置的宽度来定。抖音不支持本函数，会调用无效！
         * @param adUid 广告ID
         * @param location 位置有两种情况：1、可以传入枚举值，默认上方; 2、可以自定义位置传入IPosition，注意IPosition中的top和left跟平台的top,left是一致（没有乘以设备像素比ratio），需要开发者自己调试位置
         * @param scale 缩放比例，默认是1，即不缩放。这个缩放并不是自己填，而是根据微信MP后台你配置的原生模板广告的缩放比例填，目前有100%，90%，80%三种，一般情况不用修改。若有后台修改，记得传入值，例如90%就传入0.9。
         */
        loadCustom(adUid, location = { top: 0, left: 0 }, scale = 0.8) {
            this._custom?.destroy();
            this._custom = new ADCustom(adUid, location.top, location.left, scale);
        }

        loadCustom2(adUid, location = { top: 0, left: 0 }, scale = 0.8) {
            this._custom2?.destroy();
            this._custom2 = new ADCustom(adUid, location.top, location.left, scale);
        }

        loadCustomLeft3(adUid, location = { top: 0, left: 0 }, scale = 1) {
            this._customLeft3?.destroy();
            this._customLeft3 = new ADCustom(adUid, location.top, location.left, scale);
        }

        loadCustomRight3(adUid, location = { top: 0, left: 0 }, scale = 1) {
            this._customRight3?.destroy();
            this._customRight3 = new ADCustom(adUid, location.top, location.left, scale);
        }

        /**
         * 显示原生模板广告
         */
        showCustom() {
            if (this._custom) {
                this._custom.show();
            } else {
                console.error('MiniGameSDK: custom is null, you must call loadCustom(...) first!');
            }
        }
        showCustom2() {
            if (this._custom2) {
                this._custom2.show();
            } else {
                console.error('MiniGameSDK: custom is null, you must call loadCustom(...) first!');
            }
        }
        showCustomLeft3() {
            if (this._customLeft3) {
                this._customLeft3.show();
            } else {
                console.error('MiniGameSDK: custom is null, you must call loadCustom(...) first!');
            }
        }
        showCustomRight3() {
            if (this._customRight3) {
                this._customRight3.show();
            } else {
                console.error('MiniGameSDK: custom is null, you must call loadCustom(...) first!');
            }
        }

        /**
         * 隐藏原生模板广告
         */
        hideCustom() {
            this._custom?.hide();
        }

        hideCustom2() {
            this._custom2?.hide();
        }

        hideCustomLeft3() {
            this._customLeft3?.hide();
        }

        hideCustomRight3() {
            this._customRight3?.hide();
        }

        /**
         * 由于微信和抖音视频广告机制不同，微信可以看的视频广告个数只有0和1个，抖音平台则可以看0~maxVideoCount
         * @param adUid 广告ID。如果与上一次UID不同，则内部会重新创建实例。开发者完全不用关心这个细节。
         * @param onVideoResult 两个参数：第一个res是EAdVideoResult定义，第二count是用户看了多少个视频广告。 
         * @param target onVideoResult的拥有者
         * @param maxVideoCount 最大视频个数。默认是3，仅对抖音平台生效。微信平台看完视频count的结果永远是1或0
         */
        showVideo(adUid, onVideoResult, target, maxVideoCount = 3) {
            //onVideoResult(MiniGameSdk.EAdVideoResult.ACCEPT,1)
            if (this._video && this._video.aduid === adUid) {
                this._video.show(onVideoResult, target, maxVideoCount);
            } else {
                this._video?.destory();
                this._video = new ADVideo(adUid);
                this._video.show(onVideoResult, target, maxVideoCount);
            }
        }

        /**
         * 销毁内部所有实例，清空内存
         */
        destroyAll() {
            this._banner?.destroy();
            this._banner = null;

            this._interstitial?.destory();
            this._interstitial = null;

            this._video?.destory();
            this._video = null;

            this._custom?.destroy();
            this._custom = null;

            this._custom2?.destroy();
            this._custom2 = null;

            this._customLeft3?.destroy();
            this._customLeft3 = null;

            this._customRight3?.destroy();
            this._customRight3 = null;
        }
    }


    /**
     * 振动类型
     */
    const EVirbrateType = {
        /**
         * 短振动
         */
        SHORT: "SHORT",

        /**
         * 长振动
         */
        LONG: "LONG"
    }

    /**
     * 平台常用API合集
     */
    class API {
        static _loginCode = null;
        static _loginAnonymousCode = null;
        static _hasInitWechatCloudFunction = false;

        static autoCheckCallback(onWechat, onBytedance) {
            switch (getPlatformType()) {
                case EPlatform.DEVELOP: console.log('develop env not support!'); break;
                case EPlatform.WECHAT: onWechat?.(); break;
                case EPlatform.BYTEDANCE: onBytedance?.(); break;
                default: break
            }
        }

        /**
         * 分享app给朋友，微信小游戏分享是没有onSuccess回调的。
         * @param title 标题
         * @param description 细节描述信息 
         * @param imageUrl 图片地址
         * @param query 查询信息
         * @param onSuccess 成功回调。微信分享是不会返回的。
         */
        static shareAppToFriends(title, description = '', imageUrl, query, onSuccess) {
            let titleList = [
                "每天5分钟，锻炼一下大脑！",
                "别笑，你试你也通不了关！",
                "有本事你来过第二关呀！",
                "姐妹，来一把？",
                "智商180才能过关",
                "谁能过去第二关我就服她！",
                "休闲不伤脑，快乐一整天！！",
                "一分钟上手，三分钟上头！2024超火爆小游戏，点击即玩！",
                "1分钟上手，3分钟上头，真解压！",
                "姐妹，来一把？",
                "救命救命救命，快来帮帮小美。",
                "3分钟上手，5分钟上头，来试试你能过多少关？",
                "在线即玩，快来体验！",
                "统一回复：太解压了！",
                "小心点！这游戏可不是人人都能赢的。",
                "就这？我随便玩玩都能超越你！",
                "我赢了，你呢？敢来试试吗？",
                "通关率0.001%，你的智商够用吗？",
                "智商不足？别轻易点开！通关率仅0.001%！",
                "点点消除，开心大爆破",
                "好玩上头还解压的游戏，你也来试试",
                "来养成你的卡皮巴拉宝宝吧",
                "你有一份卡皮巴拉外卖请查收"
            ];
            let rand = Math.floor(Math.random() * titleList.length);
            title = titleList[rand];
            let arr = [
                "https://mmocgame.qpic.cn/wechatgame/Ve3hgJjFJU30mu8CeSOOOrWFRTia3ZtTrW90YNzQjX46zflCYCCiao9DsXqwIaRIdh/0",
                "https://mmocgame.qpic.cn/wechatgame/uLH7Z4C0BgfjMT4Vvich5GALI1NAZ4GxicUj9NMtDYWhUWic1pTnlRJW26Gibcw71PkS/0",
                "https://mmocgame.qpic.cn/wechatgame/g7xQamAuxvak2I0M8GIZ7416swjVoTcYaZ6BUMfmxjhiaebF15HWvdxCKgTyXXIwX/0",
                "https://mmocgame.qpic.cn/wechatgame/gjT1yiaauYWUv4oiaK0gLp00fSeuicmsVpdZarExQib558UQ983XJjNX71re73FIoPIr/0",
                "https://mmocgame.qpic.cn/wechatgame/ttLEbaxMNEZ7Rzd2ufNu4YeD9ib747ibTEQnNJqeziaibGZdLQhUa39gsWT7JgP6Acxv/0",
                "https://mmocgame.qpic.cn/wechatgame/nkYj9MyM8ibgcoS96ibScWovdZXXrbCrag5QfxHzsiabBdpHAPZ9mRXgKQIvibmnt28ib/0",
                "https://mmocgame.qpic.cn/wechatgame/hN8hPoXTbzYzK5QgRK9ibiaNP5lUq5upiaX7wdCHoYS5ibkS3TPSaB7ymPlI10RQzj6n/0",
                "https://mmocgame.qpic.cn/wechatgame/fbLj67E5GIU5iaopqw8sTV8dHrsDqN5GK5MaiblMTEgHiaYb03AeF2fg0k5zwqFnQicG/0",
                "https://mmocgame.qpic.cn/wechatgame/GuKx2jXeibhSicvMjB4oDnJRfYP2oKOt0n0xrIXWSD6oSTlKrAVVVfnd8VN1qoAvD1/0",
                "https://mmocgame.qpic.cn/wechatgame/ialqnJzmibusuHh2ibKibo3v3VfldwWfpjTeYn2ia6V2iamAdRejAZWaJS3anKP1OL29yX/0"
            ]
            let rand2 = Math.floor(Math.random() * arr.length);
            imageUrl = arr[rand2];
            this.autoCheckCallback(
                () => {
                    try {
                        //@ts-ignore
                        wx.shareAppMessage({
                            title: title,
                            imageUrl: imageUrl,
                            query: query,
                        });
                    } catch (err) {
                        console.log(`share faild: ${err}`);
                    }
                },

                () => {
                    //@ts-ignore
                    tt.shareAppMessage({
                        title: title,
                        desc: description,
                        imageUrl: imageUrl ?? '',
                        query: query ?? '',
                        success(res) {
                            console.log('share success:', res);
                            onSuccess?.();
                        },
                        fail(res) {
                            console.log('share fail:', res);
                        }
                    });
                });
        }

        /**
         * 显示提示信息
         * @param title 标题
         * @param duration 时长（单位：秒）
         * @returns 
         */
        static xianshi_toast_xiaoxi(title, duration = 2) {
            this.autoCheckCallback(
                () => {
                    // @ts-ignore
                    wx.xianshi_toast_xiaoxi({
                        title: title,
                        icon: 'success',
                        duration: duration * 1000
                    });
                },

                () => {
                    //@ts-ignore
                    tt.xianshi_toast_xiaoxi({
                        title: title,
                        duration: duration * 1000,
                        success(res) {
                            console.log(`${res}`);
                        },
                        fail(res) {
                            console.log(`showToast调用失败`);
                        },
                    });
                })
        }

        /**
         * 设备震动效果，默认为短震动。注意：可能一些机型不会生效，具体看平台方的说明
         * @param type MiniGameSdk.API.EVirbrateType
         */
        static vibrate(type = EVirbrateType.SHORT) {
            this.autoCheckCallback(
                () => {
                    switch (type) {
                        case EVirbrateType.SHORT:
                            //@ts-ignore
                            wx.vibrateShort({
                                success(res) {
                                    console.log('vibrate success:', res);
                                },
                                fail(res) {
                                    console.log('vibrateShort failed', res);
                                },
                            });
                            break;
                        case EVirbrateType.LONG:
                            //@ts-ignore
                            wx.vibrateLong({
                                success(res) {
                                    console.log('vibrate success', res);
                                },
                                fail(res) {
                                    console.log(`vibrateLong failed`, res);
                                },
                            });
                            break;
                        default:
                            break;
                    }
                },

                () => {
                    switch (type) {
                        case EVirbrateType.SHORT:
                            //@ts-ignore
                            tt.vibrateShort({
                                success(res) {
                                    console.log('vibrate success:', res);
                                },
                                fail(res) {
                                    console.log('vibrateShort failed', res);
                                },
                            });
                            break;
                        case EVirbrateType.LONG:
                            //@ts-ignore
                            tt.vibrateLong({
                                success(res) {
                                    console.log('vibrate success', res);
                                },
                                fail(res) {
                                    console.log(`vibrateLong failed`, res);
                                },
                            });
                            break;
                        default:
                            break;
                    }
                });
        }
        static gameClubButton = null;
        static createWxGameHub(leftRatio, topRatio) {
            if (cc.sys.platform != cc.sys.WECHAT_GAME) {
                return;
            }
            let windowSize = cc.view.getVisibleSize();
            // let leftRatio = pos_x / windowSize.width;
            // let topRatio = pos_y / windowSize.height;
            //@ts-ignore
            const info = wx.getSystemInfoSync();//立即获取系统信息
            const w = info.screenWidth;//屏幕宽
            const h = info.screenHeight;//屏幕高
            console.log("屏幕宽:" + w)
            console.log("屏幕高:" + h)
            let leftPos = info.windowWidth * leftRatio;
            let topPos = info.windowHeight * (topRatio);
            const biLiXi = info.windowHeight / info.windowWidth < 1.8 ? info.windowHeight / 1334 : info.windowWidth / 750;
            //console.log("posx,posy,leftRatio,topRatio,leftPos,topPos", pos_x, pos_y, leftRatio, topRatio, leftPos, topPos)
            //@ts-ignore
            MiniGameSdk.API.gameClubButton = wx["createGameClubButton"]({
                icon: '',//green dark white light
                style: {
                    left: leftPos - 5,//5,info.windowWidth - 50
                    top: topPos - 5,//150,
                    width: 100 * biLiXi,
                    height: 100 * biLiXi,
                    //backgroundColor: '#00000000',//最后两位为透明度
                    // color: '#ffffff',
                }
            })
            //return gameClubButton;
        }

        static showWxGameHub() {
            if (MiniGameSdk.API.gameClubButton) {
                MiniGameSdk.API.gameClubButton.show();
            }
        }

        static hideWxGameHub() {
            if (MiniGameSdk.API.gameClubButton) {
                MiniGameSdk.API.gameClubButton.hide();
            }
        }

        /**
         * 重启小游戏
         */
        static reboot() {
            this.autoCheckCallback(
                () => {
                    //@ts-ignore
                    wx.restartMiniProgram({
                        success: () => {
                            console.log('restart success');
                        },

                        fail: () => {
                            console.log('restart failed');
                        }
                    })
                },

                () => {
                    try {
                        // @ts-ignore
                        tt.restartMiniProgramSync();
                    } catch (error) {
                        console.log(`restartMiniProgramSync`, error);
                    }
                });
        }

        /**
         * 退出小游戏
         */
        static exit() {
            this.autoCheckCallback(
                () => {
                    //@ts-ignore
                    wx.exitMiniProgram({
                        success: () => {
                            console.log('exit success');
                        },
                        fail: () => {
                            console.log('exit failed');
                        }
                    })
                },

                () => {
                    // @ts-ignore
                    tt.exitMiniProgram({
                        success(res) {
                            console.log("exit success:", res?.data);
                        },
                        fail(res) {
                            console.log("exit fail:", res?.errMsg);
                        },
                    });
                });
        }

        /**
         * 显示转发按钮。通常在刚进入游戏的时候调用。
         * 主要是打开平台“...”这个按钮里面的分享菜单，一般默认是关闭的，需要调用这个函数打开。可以让用户分享你的游戏入口。
         */
        static showShareMenu() {
            this.autoCheckCallback(
                () => {
                    //@ts-ignore
                    wx.showShareMenu({
                        withShareTicket: true,
                        menus: ['shareAppMessage', 'shareTimeline'],
                        success: () => { },
                        fail: () => { },
                        complete: () => { }
                    });
                    let arr = [
                        "超解压打螺丝游戏，不来试试吗？",
                        "这个螺丝怎么就拧进不去呢？",
                        "这关我过不去了，快来帮帮我！",
                        "老婆晚上不睡觉，居然是在玩锤子？！",
                        "这个打螺丝的游戏很解压，快来玩！",
                        "可算是把螺丝打完了，看看我的名次吧！",
                        "又敲掉了几块木板，来比比看谁敲的多！",
                        "我名次又提升了，来围观围观！",
                        "哈哈哈哈哈，我上榜啦！",
                        "上厕所玩这个，腿都麻了！",
                        "魔性小游戏，无需下载，点击即玩！",
                        "谁设计的第二关，完全过不去啊！",
                        "解压，实在是太解压了！",
                        "我老公秒过第二关！你行不行呀",
                        "听哥一句劝，这游戏你别碰，怕你把握不住！",
                        "这关能不能一次过就看你了",
                        "有本事你来把第二关过了呀[旺柴]",
                        "该不会有人过不了第二关吧？",
                        "能过第二关的人，智商都不低于150[嘿哈]",
                        "谁能过去第2关我就服她！[左哼哼]",
                        "饭前玩一把，开心又解压[机智][呲牙]",
                        "笑死，老婆来了也过不了第二关[呲牙]",
                        "谁能过关我就服她！",
                        "据说这游戏仅0.2%的人能通过第二关，你敢来试...",
                        "这游戏你能过了第二关，算你厉害！"
                    ]
                    let url = [
                        "https://mmocgame.qpic.cn/wechatgame/icE1ziapONw2QdLct6t2bcb8OKo4VkQyP6JpdiavHp2Op6qu3p5eLZSJSpAFHBsCZaw/0",
                        "https://mmocgame.qpic.cn/wechatgame/nLSLgRZjPxDEV4J4MEoia3vNFDh9Immm3VsBYtMqVHwtn8Q92jdnzVW4YWkmrkmhe/0",
                        "https://mmocgame.qpic.cn/wechatgame/utsXsd2ePJyI5ts4gB7RBZoMH2YN0MGLP4okiaVBgQyWkMblkpl5AFgGfKsg9fdxy/0",
                        "https://mmocgame.qpic.cn/wechatgame/Fia9EBzIibl2icASdezL99x0MoYA5iaaBk7KzBahlusjpvIu1ydmgRicSVpEdMdiaxBWwJ/0",
                        "https://mmocgame.qpic.cn/wechatgame/X3tqic1tB326TdrmS0YEpBWT8Zib7pxCzTQk5LyaCjC14Y5Yw2Hyyf3rH972E3Jxyt/0",
                        "https://mmocgame.qpic.cn/wechatgame/S6UeSYDBXxD5AltyEqLBZCLPPfZM3Uibg5cA1LPVJ6U2AyCtju0XUvDBE6dLf1gic2/0",
                        "https://mmocgame.qpic.cn/wechatgame/hO680JWeI7mxe8b5iczwa0dr4RXMAbOgGNEq521GWq6pywHuPsf5pnrGk6lvx93Dw/0",
                        "https://mmocgame.qpic.cn/wechatgame/ibS2JpRdTicGTGe6xjh5Z3gztiaviat26Fr5FU9qtL9Z0Cv3rQeiaEHmN02uU155SSEc7/0",
                        "https://mmocgame.qpic.cn/wechatgame/2h12pvVhia8NfWibb8oZjYUp5Sztsf0ae6yNrvUXS88qsHmleylyWKTBct0WbtJib4c/0"

                    ]
                    //右上角点击3个点,分享给好友的设置 用户点击了“转发”按钮
                    wx["onShareAppMessage"](() => {
                        return {
                            title: arr[ShuiJiUtil.getSuiJiShu(0, arr.length - 1)],
                            imageUrl: url[ShuiJiUtil.getSuiJiShu(0, url.length - 1)], // 图片 URL
                            query: 'shareid=100' //分享参数，别人打开的时候能取到
                        }
                    })
                    //分享到朋友圈的设置，设置分享图片、标题，若不设置，则会以小游戏名称作为分享标题，以小游戏 logo 作为分享图片。
                    wx["onShareTimeline"](() => {
                        return {
                            title: arr[ShuiJiUtil.getSuiJiShu(0, arr.length - 1)],
                            imageUrl: url[ShuiJiUtil.getSuiJiShu(0, url.length - 1)], // 图片 URL
                            query: 'shareid=200' //分享参数，别人打开的时候能取到
                        }
                    })
                    wx["onShow"]((res) => {
                        console.log("onShow")
                        cc.audioEngine.resumeAll();
                        cc.audioEngine.resumeMusic();
                        MiniGameSdk.AdvertManager.instance.showInterAd();
                        if (!MiniGameSdk.AdvertManager.instance.blnFromShare) {
                            
                            //MiniGameSdk.AdvertManager.instance.showInterstitial('adunit-5de3861e3fb15afb');
                        } else {
                            MiniGameSdk.AdvertManager.instance.blnFromShare = false;
                        }


                    })
                },

                () => {
                    //@ts-ignore
                    tt.shareAppMessage({
                        success(res) {
                            console.log("show menu is showing");
                        },
                        fail(err) {
                            console.log("xianshi_fenxiang_caidan:", err.errMsg);
                        },
                        complete(res) {
                            console.log("xianshi_fenxiang_caidan complete");
                        },
                    });
                });
        }

        /**
         * 微信小游戏：跳转到另外一款小游戏
         * 抖音小游戏：跳转到指定的视频界面
         * @param targetId 微信小游戏appid或者视频界面
         */
        static navigateTo(targetId, onSuccess) {
            this.autoCheckCallback(
                () => {
                    // @ts-ignore
                    wx.navigateToMiniProgram({
                        appId: targetId,
                        extraData: {
                            foo: 'bar'
                        },
                        envVersion: 'release',
                        success(res) {
                            onSuccess?.();
                        }
                    });
                },

                () => {
                    // @ts-ignore
                    tt.navigateToVideoView({
                        videoId: targetId,
                        success: (res) => {
                            onSuccess?.();
                        },
                        fail: (err) => {
                            console.log("bytedance navigateToVideoView fail", err);
                        },
                    });
                });
        }


        /**
         * 小游戏平台登录功能。微信返回code，抖音返回code和anonymousCode。用于登录的凭证，需要把这个code传回你的服务器程序中去调用code2Session
         * @param callback (code, anonymousCode) 第一个参数为code，微信和抖音都支持；第二个参数为匿名设备ID，仅抖音支持，失败都返回null
         */
        static login(callback) {
            let platform = getPlatformType();

            let loginPlatform = () => {
                if (platform === EPlatform.WECHAT) {
                    //@ts-ignore
                    wx.login({
                        success: (res) => {
                            if (res.code) {
                                API._loginCode = res.code;
                                API._loginAnonymousCode = null;
                                callback?.(API._loginCode, API._loginAnonymousCode);
                            } else {
                                console.log('login error:', res.errMsg)
                            }
                        },

                        fail: () => {
                            API._loginCode = null;
                            API._loginAnonymousCode = null;
                            callback?.(API._loginCode, API._loginAnonymousCode);
                            console.log('login fail')
                        }
                    });
                } else if (platform === EPlatform.BYTEDANCE) {
                    //@ts-ignore
                    tt.login({
                        force: true,
                        success(res) {
                            console.log(`login ${res.code} ${res.anonymousCode}`);
                            if (res.code) {
                                API._loginCode = res.code?.toString();
                                API._loginAnonymousCode = res.anonymousCode?.toString();
                                callback?.(API._loginCode, API._loginAnonymousCode);
                            } else {
                                console.log('login error:', res.errMsg)
                            }
                        },
                        fail(res) {
                            API._loginCode = null;
                            API._loginAnonymousCode = null;
                            callback?.(API._loginCode, API._loginAnonymousCode);
                            console.log(`login fail`, res);
                        },
                    });
                } else {
                    API._loginCode = null;
                    API._loginAnonymousCode = null;
                    callback?.(API._loginCode, API._loginAnonymousCode);
                    console.log('not mini game platform, login codes are all null');
                }
            }



            if (!API._loginCode) {
                loginPlatform();
            } else {
                if (platform === EPlatform.WECHAT) {
                    //@ts-ignore
                    wx.checkSession({
                        success() {
                            console.log(`session is valid, use current code:`, API._loginCode);
                            callback?.(API._loginCode, API._loginAnonymousCode);
                        },
                        fail() {
                            console.log(`session expired`);
                            loginPlatform();
                        }
                    });
                } else if (platform === EPlatform.BYTEDANCE) {
                    //@ts-ignore
                    tt.checkSession({
                        success() {
                            console.log(`session is valid, user current code: ${API._loginCode}, ${API._loginAnonymousCode}`);
                            callback?.(API._loginCode, API._loginAnonymousCode);
                        },
                        fail() {
                            console.log(`session expired`);
                            loginPlatform();
                        },
                    });

                } else {
                    console.log('not mini game platform, login null');
                    callback?.(null, null);
                }
            }
        }

        /**
         * 调用微信云函数。由于参数需要自定义，所以为any，需要自行解释。函数只完成通道和处理一场的作用
         * @param callback 返回云函数调用结果。需要检查返回参数是否为空，失败的时候为空
         * @param name 云函数的名字
         * @param data 云函数的内容
         */
        static callWechatCloudFunction(callback, name, data) {
            if (!isWechat()) {
                console.log('Not wechat platform, not support callWechatCloudFunction');
                return;
            }

            this.login((code, anonymousCode) => {
                if (!API._hasInitWechatCloudFunction) {
                    //@ts-ignore
                    wx.cloud.init();
                    API._hasInitWechatCloudFunction = true;
                }
                //@ts-ignore
                wx.cloud.callFunction({
                    name: name,
                    data: data,
                    success: (res) => callback?.(res),
                    fail: (err) => {
                        console.log('wechat cloud function error:', err);
                        callback?.(null);
                    }
                });
            });
        }

        /**
         * 存储用户信息，数据量不能大。可以考虑用于分数排行榜。用户之间可共享排行数据。
         * @param key 
         * @param value 
         */
        static setUserCloudStorage(key, value) {
            this.autoCheckCallback(
                () => {
                    // @ts-ignore
                    wx.setUserCloudStorage({
                        KVDataList: [{ key: key, value: value }],
                        success: () => console.log(`set cloud storage success:${key}, value:${value}`),
                        fail: (err) => console.log('set cloud storage error:', err)
                    });
                },

                () => {
                    // @ts-ignore
                    tt.setUserCloudStorage({
                        KVDataList: [{ key: key, value: value, }],
                        success: () => console.log(`set cloud storage success:${key}, value:${value}`),
                        fail: (err) => console.log('set cloud storage error:', err)
                    });

                }
            )
        }
    }


    /**
     * 抖音侧边栏专属接口
     */
    class BytedanceSidebar {
        /**
         * 本游戏在抖音环境下启动监控，需要放在全局环境中，保证能第一时间启动。因为可能监听抖音失败（抖音小游戏官方的说明）！
         * @param onResult 包含一个boolean参数的函数
         * @param target 上述函数的拥有者，如果是类的成员函数，需要传入this。普通或匿名函数忽略即可。
         */
        static listenFromSidebar(onResult, target) {
            if (!isBytedance()) {
                onResult?.call(target, false);
                return;
            }
            // @ts-ignore
            tt.onShow((res) => {
                console.log('onShow launch res:', res);
                if (res.scene === '021036') {
                    onResult?.call(target, true);
                    console.log('launch from sidebar');
                } else {
                    onResult?.call(target, false);
                    console.log('NOT launch from douyin sidebar!');
                }
            });

            // @ts-ignore
            let options = tt.getLaunchOptionsSync();
            if (options && options.scene === '021036') {
                onResult?.call(target, true);
            }
        }

        /**
         * 检测抖音侧边栏是否存在
         * @param onResult 包含一个boolean参数的函数
         * @param target 上述函数的拥有者，如果是类的成员函数，需要传入this。普通或匿名函数忽略即可。
         * @returns 
         */
        static checkSideBar(onResult, target) {
            if (!isBytedance()) {
                onResult?.call(target, false);
                return;
            }

            //@ts-ignore
            tt.jiancha_dangqian_changjing({
                scene: "sidebar",
                success: (res) => {
                    console.log("check scene success: ", res.isExist);
                    onResult?.call(target, res.isExist);

                },
                fail: (res) => {
                    console.log("check scene fail:", res);
                    onResult?.call(target, false);
                }
            });
        }

        /**
         * 跳转到抖音侧边栏
         * @param onResult 包含一个boolean参数的函数
         * @param target 上述函数的拥有者，如果是类的成员函数，需要传入this。普通或匿名函数忽略即可。
         * @returns 
         */
        static navigateToSidebar(onResult, target) {
            if (!isBytedance()) {
                console.log("not douyin platform!");
                onResult?.call(target, false);
                return;
            }

            // @ts-ignore
            tt.navigateToScene({
                scene: "sidebar",
                success: () => {
                    console.log("navigate success");
                    onResult?.call(target, true);
                },
                fail: (res) => {
                    console.log("navigate failed reason:", res);
                    onResult?.call(target, false);
                },
            });
        }
    }


    return {
        ISize,
        IPosition,
        EPlatform,

        isWechat,
        isBytedance,
        getPlatformType,
        getPlatformSystemWindowSize,
        ADInterstitial,
        ADBanner,
        ADCustom,
        EAdVideoResult,
        ADVideo,
        EAdBannerLocation,
        AdvertManager,
        EVirbrateType,
        API,

        BytedanceSidebar,
    }

})();